// CoachAnalyser.cpp

// Analyza protivnika, odporucanie obrannej a utocnej formacie koucovi, textovy vystup analyzy do suboru

#include "CoachAnalyser.h"
//#include "Player/Formation.h"
#include <memory.h>
#include <stdio.h>

// Konstruktor
CoachAnalyser::CoachAnalyser()
{
	Reset();
}

// Destruktor
CoachAnalyser::~CoachAnalyser()
{
}

// Najde najvhodnejsiu subformaciu pre utok
unsigned CoachAnalyser::CountAttackFitness(Formation *f)
{
	Point p; // pomocna premenna, pozicia hraca v subformacii
	int i,j,k, form;
	float opposition = 0, min = 100000; 
	unsigned bestsubformation = 0; // odporucana subformacia

	float obstacles[FIELDHEIGHT/SECTORSIZE]; // prekazky v utoku
	memset(obstacles, 0, sizeof(float) * FIELDHEIGHT/(SECTORSIZE));

	for (i = 0; i < FIELDHEIGHT/SECTORSIZE; i++)
		// pocitame prekazky od stredu ihriska smerom ku brane
		for (k = (FIELDWIDTH/2)/SECTORSIZE; k < FIELDWIDTH/SECTORSIZE; k++)
			obstacles[i] += field[k][i];

	// Zoberieme z utocnej subformacie y suradnicu hracov, zistime,
	// do ktoreho sektoru prislucha a +-1(2) sektory okolo daneho sektoru
	// budeme scitavat odpor protihracov a hladat minimalne pokrytie 
	// v danych riadkoch(sektorovych)
	for(form=0; form < f->GetUnitsCount(); form++)
	{
		if (f->GetPlayersCountInUnit(form) < 3) 
			continue;
		
		opposition = 0.0f;
		
		for(i = 0; i < f->GetPlayersCountInUnit(form); i++)
		{
			p = f->GetPlayerPosInUnit(form, i);
			p.SetY(p.GetY() + FIELDHEIGHT / 2.0f);
			for(j =((int)(p.GetY() / 2.0f)) - 2; j < ((int)(p.GetY() / 2.0f)) + 2; j++)
				opposition += obstacles[j];
		}
		if(opposition / f->GetPlayersCountInUnit(form) < min)
		{
			bestsubformation=form;
			min = opposition / f->GetPlayersCountInUnit(form);
		}
	}
	
	return bestsubformation;
}

// Najde najvhodnejsiu subformaciu pre obranu
unsigned CoachAnalyser::CountDefenceFitness(Formation * f)
{
	int i,j, offset, form;
	unsigned bestformation, bestoffset;
	float max = 0, fitness;
	float ohodnotenie[35][11];
	Point p;
	// pre vsetky formacie
	for (form = 0; form < f->GetUnitsCount(); form++)
//		if(f->GetUnitType(form) {		// tato funkcia neexistuje, typy formacii tam su, ale nevyuzivaju sa
		// pre vsetky offsety danej formacie
	{
		if (f->GetPlayersCountInUnit(form) < 3) 
			continue;
		for (offset = 0; offset < MAXOFFSET; offset += SECTORSIZE)
		{
			fitness = 0.0f;
			f->GetUnitCoverage(form, ohodnotenie);
			p = f->GetUnitDimensions(form);
			// pre cele pole, ktore moze subformacia pokryt
			for (i = 0; i < p.GetX()/*FIELDHEIGHT/SECTORSIZE*/; i++)
				for (j = 0; j  < p.GetY()/*f->GetUnitWidth(form)*/; j++)
					fitness += field[offset/SECTORSIZE+j][i] * ohodnotenie[i][j];
			//ak je formacia lepsia, zapamatame	
			if (fitness / f->GetPlayersCountInUnit(form) > max)
			{
				bestformation = form;
				bestoffset = offset / 2;
				max = fitness / f->GetPlayersCountInUnit(form);
			}
		}
	}
	// vratim v cisle zakodovanu formaciu a offset
	return 100 * bestformation + bestoffset - 1; // ta -1 je ladiaca konstanta, aby umiestnoval obranu medzi utocnikov a branu.
}

// Vytlaci analyzu do textoveho suboru
void CoachAnalyser::PrintToFile(const char *file)
{
	FILE *f;
	
	if(!(f = fopen(file, "w")))
	{
		printf("Error opening file");
	}
	else
	{
		for(int i = 0; i < FIELDHEIGHT/SECTORSIZE; i++)
		{
			for(int j = 0; j < FIELDWIDTH/SECTORSIZE; j++)
				fprintf(f, "%5d", field[j][i]);
			fprintf(f, "\n");
		}
	}

}

void CoachAnalyser::Reset()
{
	for(int i = 0; i < FIELDWIDTH/SECTORSIZE; i++)
//		for(int j = 0; j < FIELDHEIGHT/SECTORSIZE; j++)
//			field[i][j] = 0;
		memset(&field[i], 0, sizeof(unsigned) * FIELDHEIGHT/SECTORSIZE); 

}


// Doplni do field posledne visual_info od kouca
void CoachAnalyser::Update(const COACH_VISUAL_INFO *vi)
{
	for(int i = 0;i<vi->theirCount; i++)
	{
		if (vi->their[i].goalie) continue;
		int x = (int)((vi->their[i].pos.GetX() + FIELDWIDTH/2.0) / SECTORSIZE);
		int y = (int)((vi->their[i].pos.GetY() + FIELDHEIGHT/2.0) / SECTORSIZE);
		field[x][y]++;
	}
}







